/**
 * Java基本锁
 *  1.公平锁：公平锁就是很公平，在并发环境中，每个线程在获取锁时会先查看此锁维护的等待队列，如果为空，或者当前线程是等待队列的第一个，就占有锁，否则就会加入到等待队列中，以后会按照FIFO的规则从队列中取到自己。
 *          代表：
 *              1.new ReentrantLock(true)
 *
 *  2.非公平锁：非公平锁比较粗鲁，上来就直接尝试占有锁，如果尝试失败，就再采用类似公平锁那种方式。
 *          代表：
 *              1.Synchronized
 *              2.new ReentrantLock(false)
 *
 *  3.可重入锁（递归锁）：线程可以进入任何一个它已经拥有的锁所同步着的代码块。可重入锁最大的作用是避免死锁。
 *          代表：
 *              1.Synchronized monitorObject
 *              2.new ReentrantLock AQS state
 *
 *  4.自旋锁：是指尝试获取锁的线程不会立即阻塞，而是采用循环的方式去尝试获取锁，这样的好处是减少线程上下文切换的消耗，缺点是循环会消耗CPU。依赖CAS和循环
 *           代表：
 *              1.AtomicInteger
 *              2.各种原子类 unsafe.cas() + while()
 *
 *  5.共享锁（读锁）：指该锁可被多个线程所持有
 *                 代表：
 *                      1.ReentrantReadWriteLock.readLock
 *
 *  6.独占锁（写锁）：指该锁一次只能被一个线程所持有。对ReentrantLock和Synchronized而言都是独占锁
 *
 *  7.读写锁：多个线程同时读一个资源类没有任何问题，所以为了满足并发量，读取共享资源应该可以同时进行。但是，如果有一个线程想去写共享资源，就不应该再有其它线程可以对该资源进行读或写。
 *           代表：
 *              1.ReentrantReadWriteLock
 *
 *    偏向锁 / 轻量级锁 / 重量级锁:
 *      锁的状态是通过对象监视器在对象头中的字段来表明的。四种状态会随着竞争的情况逐渐升级，而且是不可逆的过程，即不可降级。这四种状态都不是Java语言中的锁，而是Jvm为了提高锁的获取与释放效率而做的优化(使用synchronized时)。
 *      偏向锁:
 *          偏向锁是指一段同步代码一直被一个线程所访问，那么该线程会自动获取锁。降低获取锁的代价。
 *      轻量级:
 *          轻量级锁是指当锁是偏向锁的时候，被另一个线程所访问，偏向锁就会升级为轻量级锁，其他线程会通过自旋的形式尝试获取锁，不会阻塞，提高性能。
 *      重量级锁:
 *          重量级锁是指当锁为轻量级锁的时候，另一个线程虽然是自旋，但自旋不会一直持续下去，当自旋一定次数的时候，还没有获取到锁，就会进入阻塞，该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞，性能降低。
 *
 *  8.synchronized 与 lock 区别：
 *      1.synchronized属于JVM层面，属于java的关键字
 *          1) monitorenter（底层是通过monitor对象来完成，其实wait/notify等方法也依赖于monitor对象 只能在同步块或者方法中才能调用 wait/ notify等方法）
 *          2) Lock是具体类（java.util.concurrent.locks.Lock）是api层面的锁
 *      2.使用方法：
 *          1) synchronized：不需要用户去手动释放锁，当synchronized代码执行后，系统会自动让线程释放对锁的占用。
 *          2) ReentrantLock：则需要用户去手动释放锁，若没有主动释放锁，就有可能出现死锁的现象，需要lock() 和 unlock() 配置try catch语句来完成
 *      3.等待是否中断
 *          1) synchronized：不可中断，除非抛出异常或者正常运行完成。
 *          2) ReentrantLock：可中断，可以设置超时方法
 *              a. 设置超时方法，trylock(long timeout, TimeUnit unit)
 *              b. lockInterrupible() 放代码块中，调用interrupt() 方法可以中断
 *      4.加锁是否公平
 *          1) synchronized：非公平锁
 *          2) ReentrantLock：默认非公平锁，构造函数可以传递boolean值，true为公平锁，false为非公平锁
 *      5.锁绑定多个条件Condition
 *          1) synchronized：没有，要么随机，要么全部唤醒
 *          2) ReentrantLock：用来实现分组唤醒需要唤醒的线程，可以精确唤醒，而不是像synchronized那样，要么随机，要么全部唤醒
 *
 * Java多线程通知工具类
 *  1.CountDownLatch：线程倒数（秦灭六国），让一线程阻塞直到另一些线程完成一系列操作才被唤醒。依赖AQS框架共享模式
 *                  主要方法：
 *                        await() 当一个或多个线程调用await()时，调用线程会被阻塞
 *                        countDown() 其它线程调用countDown()会将计数器减1 当计数器的值变为零时，因调用await方法被阻塞的线程会被唤醒，继续执行。
 *
 *  2.CyclicBarrier：与CountDownLatch含义相反（收集龙珠），基于Condition通知唤醒机制实现
 *                  让一组线程到达一个屏障（也可以叫同步点）时被阻塞，直到最后一个线程到达屏障时，屏障才会开门，所有被屏障拦截的线程才会继续干活，线程进入屏障通过CyclicBarrier的await方法。
 *
 *  3.CyclicBarrier与CountDownLatch的区别：CyclicBarrier可重复多次，而CountDownLatch只能是一次。
 *
 *  4.semaphore：信号量，主要用于两个目的，一个是用于多个共享资源的互斥使用，另一个用于并发线程数的控制。依赖AQS框架
 *
 *  Java阻塞队列
 *
 */
package com.wzw.basics.concurrent.lock;